package labuladong.leetcode.editor.cn;

public class _704_BinarySearch {

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public int search(int[] nums, int target) { //常用
            int left = 0;
            int right = nums.length - 1; // 注意

            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target)
                    return mid;
                else if (nums[mid] < target)
                    left = mid + 1; // 注意
                else if (nums[mid] > target)
                    right = mid - 1; // 注意
            }
            return -1;
        }

        public int search2(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1; // 注意
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target)
                    return mid;
                else if (nums[mid] < target)
                    left = mid + 1; // 注意
                else if (nums[mid] > target)
                    right = mid - 1; // 注意
            }
            return nums[left] == target ? left : -1;
        }

        public int search3(int[] nums, int target) {
            int left = 0;
            int right = nums.length; // 注意

            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target)
                    return mid;
                else if (nums[mid] < target)
                    left = mid + 1; // 注意
                else if (nums[mid] > target)
                    right = mid - 1; // 注意
            }
            return -1;
        }

        int left_bound(int[] nums, int target) {  //常用
            int left = 0;
            int right = nums.length; // 注意

            while (left < right) { // 注意
                int mid = left + (right - left) / 2;
                if (nums[mid] == target) {
                    right = mid;
                } else if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid; // 注意
                }
            }
            return left;
        }

        int left_bound2(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            // 搜索区间为 [left, right]
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    // 搜索区间变为 [mid+1, right]
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    // 搜索区间变为 [left, mid-1]
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    // 收缩右侧边界
                    right = mid - 1;
                }
            }
            // 判断 target 是否存在于 nums 中
            // 此时 target 比所有数都大，返回 -1
            if (left == nums.length) return -1;
            // 判断一下 nums[left] 是不是 target
            return nums[left] == target ? left : -1;
        }

        int right_bound(int[] nums, int target) {  //常用
            int left = 0, right = nums.length;

            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target) {
                    left = mid + 1; // 注意
                } else if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid;
                }
            }
            return left - 1; // 注意
        }

        int right_bound2(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    // 这里改成收缩左侧边界即可
                    left = mid + 1;
                }
            }
            // 最后改成返回 left - 1
            if (left - 1 < 0) return -1;
            return nums[left - 1] == target ? (left - 1) : -1;
        }
    }
//leetcode submit region end(Prohibit modification and deletion)


    public static void main(String[] args) {
        Solution solution = new _704_BinarySearch().new Solution();
        int[] nums = {-1, 0, 3, 5, 9, 12};
        System.out.println(solution.search(nums, 9));
    }
}
